from django.http import Http404, HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse
from django.template import RequestContext
from django.contrib.auth.decorators import login_required

from modular import models, Module
from modular.forms import form_for_module

def _limit_to_user(view):
    """
    Make sure the module being request belongs to the current user.
    """
    def wrapper(request, module_id, *args, **kwargs):
        try:
            module = Module._from_id(module_id)
        except models.Module.DoesNotExist:
            raise Http404
        if module.user != request.user:
            raise Http404
        return view(request, module, *args, **kwargs)
    return wrapper

def _redirect_to_module(module_id):
    # Redirect to the module renderer
    url = reverse('modular.views.get_module', kwargs={'module_id':module_id})
    return HttpResponseRedirect(url)

def get_module(request, module):
    """
    Retrieve the markup for just the specified module.
    """
    return HttpResponse(module.render())
get_module = _limit_to_user(get_module)

def list_modules(request):
    modules = [klass(request.user) for klass in Module.get_all_modules()]
    return render_to_response('modular/module_list.html', {
        'available_modules': modules,
    }, context_instance=RequestContext(request))

def add_module(request, module_type):
    """
    Edit the preferences for a new module.
    """
    module = Module._from_name(module_type)(request.user)

    ModuleForm = module.get_form()

    if request.method == 'POST':
        form = ModuleForm(request.POST.copy())
        if not form.errors:
            for name in form.fields.keys():
                module._record.preferences[name] = form.cleaned_data[name]
            module._record.save()

            return _redirect_to_module(module._record._get_pk_val())
    else:
        form = ModuleForm()

    return render_to_response('modular/module_form.html', {
        'form': form,
        'module': module,
    }, context_instance=RequestContext(request))
add_module = login_required(add_module)

def edit_module(request, module):
    """
    Edit the preferences for the specified module.
    """
    ModuleForm = module.get_form()

    if not ModuleForm.base_fields:
        raise Http404

    if request.method == 'POST':
        form = ModuleForm(request.POST.copy())
        if not form.errors:
            for name in form.fields.keys():
                module._record.preferences[name] = form.cleaned_data[name]
            module._record.save()

            return _redirect_to_module(module.id)
    else:
        form = ModuleForm()

    return render_to_response('modular/module_form.html', {
        'form': form,
        'module': module,
    }, context_instance=RequestContext(request))
edit_module = _limit_to_user(edit_module)

def remove_module(request, module):
    """
    Remove the specified module from the user's list
    """
    request.user.module_set.remove(module)
remove_module = _limit_to_user(remove_module)

def arrange_modules(request):
    # TODO: Implement a way a arrange modules using the position attribute
    raise Http404
